package common

import (
	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"net/http"
	"runtime/debug"
)

func ServiceContextMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		svc := NewServiceContext(c)
		c.Set("svc", svc)
		c.Next()
	}
}

// RequestIdMiddleware 中间件，为每个请求自动生成和设置 requestId 到 context
func RequestIdMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 为当前请求生成新的 requestId
		ctx := WithRequestId(c.Request.Context())

		// 更新请求的 context
		c.Request = c.Request.WithContext(ctx)

		c.Next()
	}
}

func After() gin.HandlerFunc {

	return func(c *gin.Context) {
		// 设置 example 变量
		//fmt.Println(c.GetHeader("header"))
		// 获取GET请求的查询参数
		//fmt.Println("name参数:", c.Query("name"))           // 获取单个参数
		//fmt.Println("age参数:", c.DefaultQuery("age", "0")) // 获取参数，如果不存在则返回默认值
		//fmt.Println("所有参数:", c.Request.URL.Query())       // 获取所有查询参数
		//svc := NewServiceContext(c)
		//svc.LogClient.Info(svc.RequestId)
		//c.Next()

		// 请求前
		c.Next()
		// 请求后

	}
}

// ErrorHandler 错误处理中间件
func ErrorHandler() gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Next()
		// 处理请求过程中的错误
		if len(c.Errors) > 0 {
			err := c.Errors.Last()
			logger := WithContext(c.Request.Context())
			logger.WithFields(logrus.Fields{
				"method": c.Request.Method,
				"path":   c.Request.URL.Path,
				"ip":     c.ClientIP(),
				"error":  err.Error(),
			}).Error("请求处理错误")

			c.JSON(http.StatusInternalServerError, gin.H{
				"error":      "内部服务器错误",
				"code":       500,
				"request_id": GetRequestId(c.Request.Context()),
			})
			return
		}

		// 处理404错误
		if c.Writer.Status() == 404 {
			logger := WithContext(c.Request.Context())
			logger.WithFields(logrus.Fields{
				"method": c.Request.Method,
				"path":   c.Request.URL.Path,
				"ip":     c.ClientIP(),
			}).Warn("路由不存在")

			c.JSON(http.StatusNotFound, gin.H{
				"error":      "路由不存在",
				"code":       404,
				"path":       c.Request.URL.Path,
				"request_id": GetRequestId(c.Request.Context()),
			})
			return
		}
	}
}

// RecoveryHandler panic恢复中间件
func RecoveryHandler() gin.HandlerFunc {
	return gin.CustomRecovery(func(c *gin.Context, recovered interface{}) {
		logger := WithContext(c.Request.Context())
		logger.WithFields(logrus.Fields{
			"method": c.Request.Method,
			"path":   c.Request.URL.Path,
			"ip":     c.ClientIP(),
			"panic":  recovered,
			"stack":  string(debug.Stack()),
		}).Error("服务器发生panic")

		c.JSON(http.StatusInternalServerError, gin.H{
			"error":      "服务器内部错误",
			"code":       500,
			"request_id": GetRequestId(c.Request.Context()),
		})
	})
}
